<?php


namespace KernelModule\LogsModule\PhpModule;

use Nette\Object;
use Nette\Environment;

use Celebrio\Logging\DownloadLogsException;
use Celebrio\Logging\AzureContainerException;
use \KernelModule\LogsModule\NotAnySpaceForLogsException;
use \KernelModule\LogsModule\NotEnoughDiskSpaceException;

use Celebrio\Logging\AzureLogHandling;
use Celebrio\WindowsAzure\AzureStorage\AzureStorageBLOB;
use \Microsoft_WindowsAzure_Storage_Blob;


/**
 * Azure log downloading and transformation
 *
 * @author Robert
 */
class AzureLogs extends Object {
    private static $tempDirName = "tempAzureLogs";
    
    private static $diskSpaceToLeaveFreeBytes = 10485760;//10*1024*1024 = 10 MB //change
          
    public function downloadLogsFromAzure() { 
        $containerName = AzureLogHandling::getContainerName();
        //create temp log file in log directory to store downloaded logs
        $tempLogDir = Environment::expand("%logDir%") . DIRECTORY_SEPARATOR . self::$tempDirName;
        if (!file_exists($tempLogDir)) {
            mkdir($tempLogDir);
        } else if ($handle = opendir($tempLogDir)) {
            while (false !== ($fileName = readdir($handle))) { 
                if($fileName != "." && $fileName != "..") {
                    unlink($tempLogDir . DIRECTORY_SEPARATOR . $fileName);
                }             
            }
            closedir($handle);
        }
         
        //download logs from azure storage
        try {          
            if(AzureStorageBLOB::connection()->containerExists($containerName)) {
                if(disk_free_space($tempLogDir) > self::$diskSpaceToLeaveFreeBytes) {
                    $azureLogFile = AzureLogHandling::getAzureLogFileName();
                    if(AzureStorageBLOB::connection()->blobExists($containerName, $azureLogFile)) {
                        AzureStorageBLOB::connection()->getBlob($containerName, $azureLogFile , $tempLogDir . DIRECTORY_SEPARATOR .$azureLogFile);
                    } else {
                        throw new DownloadLogsException(_("File for logs($azureLogFile) is missing on azure storage"));
                    }
                    
                    $blobList = AzureStorageBLOB::connection()->listBlobs($containerName);
                    foreach ($blobList as $blob) {
                        //TODO: very temporary solution, if free disk space is lesser than specified value, downloading logs will stop
                        // and ask you to delete all logs to make more space
                        if(disk_free_space($tempLogDir) < self::$diskSpaceToLeaveFreeBytes ) {
                            throw new NotEnoughDiskSpaceException(_("There is not enough space on server disk for more logs. Delete old logs from Azure storage or expand disk space."));
                        }
                        $blobName = $blob->Name;
                        if ($blobName !== $azureLogFile) {
                            AzureStorageBLOB::connection()->getBlob($containerName, $blobName , $tempLogDir . DIRECTORY_SEPARATOR . $blobName);
                        } 
                    }  
                } else {
                    throw new NotAnySpaceForLogsException(_("There is no space on the disk left for logs. Expand your disk space to see logs."));
                }
            } else {
                throw new AzureContainerException(_("Container for logs doesn't exist in Azure storage."));
            }
        } catch (Microsoft_WindowsAzure_Exception $e) {
            throw new DownloadLogsException(_("There was a problem with downloading blobs from Azure storage."));
        }
    }
    
    
    public function deleteLocalLogs($dir) {
        //names of log files to delete
        $toDelete = array(
            "%logPHPErr%",
            "%logPHPClean%",
            "%logPHPCount%",
            "%logPHPWork%",
            "%logPHPHash%"
        );
        foreach ($toDelete as $file) {
            $filePath = $dir . DIRECTORY_SEPARATOR . Environment::expand($file);
            if( file_exists($filePath) ) {
                unlink($filePath);
            }            
        }
        
        if ($handle = opendir($dir)) {
            while (false !== ($fileName = readdir($handle))) {
                if(!(strpos($fileName, "exception") === false)) {
                    unlink($dir . DIRECTORY_SEPARATOR . $fileName);
                }
            }
            closedir($handle);
        }
    }
    
    /*
     * Replaces local log files on server with log files from azure temp folder
     */
    public function moveLogsFromTemp() {
        $logDir = Environment::expand('%logDir%');
        $tempLogDir = $logDir . DIRECTORY_SEPARATOR . self::$tempDirName;
        if ($handle = opendir($tempLogDir)) {
            while (false !== ($fileName = readdir($handle))) {
                if($fileName != "." && $fileName != "..") {
                    if(!(strpos($fileName, AzureLogHandling::getAzureLogFileName()) === false)) {
                        rename($tempLogDir . DIRECTORY_SEPARATOR . $fileName, 
                                $tempLogDir . DIRECTORY_SEPARATOR . Environment::expand("%logPHPErr%"));
                        $fileName = Environment::expand("%logPHPErr%");
                    }
                    copy($tempLogDir. DIRECTORY_SEPARATOR . $fileName, $logDir . DIRECTORY_SEPARATOR . $fileName);
                    unlink($tempLogDir. DIRECTORY_SEPARATOR . $fileName);
                }
            }
            closedir($handle);
        }            
    }
}